GuardDutyの抑制ルールをCLIで設定する(サンプルあり)
みなさん GuardDuty を使ってアラートを検知する仕組みは実装してるでしょうか。
AWS アカウントを作ったら以下のブログのように、やるべきことの 1 つに GuardDuty の有効化が挙げられています。また通知の実装も合わせてやることが推奨されています。
そんな GuardDuty ですが、運用していると一時的な作業の際に過検知により通知が多く飛んでしまうケースがあります。同じ作業を繰り返すケースや長期化する場合は、通知のノイズを減らすために通知を抑制が可能です。
その抑制するための機能が GuardDuty の「抑制ルール」です。
抑制ルールとは
抑制ルールとは「指定した条件に一致する新しい検出結果を自動的にアーカイブする」機能です。抑制ルールを作成した後、条件に一致する検出結果は全てアーカイブされます。 その際 CloudWatch イベントは発生しません。
また、設定できる条件は「フィルター」を使って作成します。フィルターで設定できる属性は以下のドキュメントを参照してください。
今回は CLI でサクッと抑制したい時に使えるコマンドを作成したので、一時的に抑制ルールを作成したい場合にご利用ください。
抑制ルール作成の流れ
CloudShell に貼り付けて利用してください。
抑制ルールを作成する前に GuardDuty の detectorId を変数に入れておきましょう。
DETECTOR_ID=$(aws guardduty list-detectors --query 'DetectorIds[0]' --output text)
サンプルとしてBackdoor:Runtime/C&CActivity.B
を抑制するコマンドを実行してみます。finding-criteria
の type で設定されている部分を書き換えれば、他の Finding を抑制できます。用途に合わせてname
とdescription
も合わせて変更してください。
aws guardduty create-filter \
--detector-id "$DETECTOR_ID" \
--name "SuppressBackdoor" \
--description "Suppress Backdoor" \
--finding-criteria '{"Criterion": {"type": {"Eq":["Backdoor:Runtime/C&CActivity.B"]}}}'
GuardDuty の「検出結果のサンプルを生成」を実行した後、上記の抑制ルールでフィルターされる結果を確認してみます。
Backdoor:Runtime/C&CActivity.B
を対象にする場合、サンプルでは 4 つの Findings が対象となりました。これでも良いのですが、抑制したいリソースが明確な場合はより具体的なルールを作成するのが望ましいです。
今回の場合、リソースは以下の 4 つに分類されています。
- Container
- ECSCluster
- Instance
- EKSCluster
この中でリソースがInstance
の結果だけを抑制するルールを作成します。先ほどのコマンドに{"service.resourceType": {"Eq": ["Instance"]}
を追加しました。
aws guardduty create-filter \
--detector-id "$DETECTOR_ID" \
--name "SuppressBackdoorInstances" \
--description "Suppress Backdoor for Instance resources" \
--finding-criteria '{"Criterion": {"type": {"Eq":["Backdoor:Runtime/C&CActivity.B"]},"service.resourceType": {"Eq": ["Instance"]}}}'
この条件で作成した結果を確認すると、リソースが Instance のものに絞られていますね。
このような形で抑制したい検出結果に合わせてコマンドを作成しておくと便利です。追加する際の記述方法は CLI のドキュメントを参照してください。
その他のサンプル
よくある検出結果の抑制サンプルを載せておきます。
Recon:EC2/PortProbeUnprotectedPort
ポートスキャンを受けているポートを意図して公開している場合は抑制ルールを作成します。{任意のタグ}
は抑制ルールを作成したいインスタンスのタグキーに置き換えてください。
※インスタンスを識別するためタグキーは必須にしています。
FINDING_ID={検知された検出結果ID}
TAG_KEY={任意のタグ}
DETECTOR_ID=$(aws guardduty list-detectors --query 'DetectorIds[0]' --output text)
FINDING_DETAILS=$(aws guardduty get-findings --detector-id "$DETECTOR_ID" --finding-ids "$FINDING_ID" --query 'Findings[0]' --output json)
TAG_VALUE=$(echo "$FINDING_DETAILS" | jq -r '.Resource.InstanceDetails.Tags[] | select(.Key == "'$TAG_KEY'") | .Value')
aws guardduty create-filter \
--detector-id "$DETECTOR_ID" \
--name "SuppressPortProbeUnprotectedPort" \
--description "Suppress PortProbeUnprotectedPort for instances with specific tag" \
--finding-criteria "{\"Criterion\": {\"type\": {\"Eq\": [\"Recon:EC2/PortProbeUnprotectedPort\"]}, \"resource.resourceType\": {\"Eq\": [\"Instance\"]}, \"resource.instanceDetails.tags.key\": {\"Eq\": [\"$TAG_KEY\"]}, \"resource.instanceDetails.tags.value\": {\"Eq\": [\"$TAG_VALUE\"]}}}"
Recon:EC2/Portscan
脆弱性スキャンを EC2 で行うなど、意図してポートスキャンを行っている場合に検知されます。{任意のタグ}
は抑制ルールを作成したいインスタンスのタグキーに置き換えてください。
※インスタンスを識別するためタグキーは必須にしています。
FINDING_ID={検知された検出結果ID}
TAG_KEY={任意のタグ}
DETECTOR_ID=$(aws guardduty list-detectors --query 'DetectorIds[0]' --output text)
FINDING_DETAILS=$(aws guardduty get-findings --detector-id "$DETECTOR_ID" --finding-ids "$FINDING_ID" --query 'Findings[0]' --output json)
TAG_VALUE=$(echo "$FINDING_DETAILS" | jq -r '.Resource.InstanceDetails.Tags[] | select(.Key == "'$TAG_KEY'") | .Value')
aws guardduty create-filter \
--detector-id "$DETECTOR_ID" \
--name "SuppressPortscan" \
--description "Suppress Portscan for instances with specific tag" \
--finding-criteria "{\"Criterion\": {\"type\": {\"Eq\": [\"Recon:EC2/Portscan\"]}, \"resource.resourceType\": {\"Eq\": [\"Instance\"]}, \"resource.instanceDetails.tags.key\": {\"Eq\": [\"$TAG_KEY\"]}, \"resource.instanceDetails.tags.value\": {\"Eq\": [\"$TAG_VALUE\"]}}}"
UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS
EC2 の IAM ロールの認証情報をオンプレミスのプロキシサーバーやゲートウェイで利用している場合、検知されることがあります。
FINDING_ID={検知された検出結果ID}
DETECTOR_ID=$(aws guardduty list-detectors --query 'DetectorIds[0]' --output text)
IP_ADDRESS=$(aws guardduty get-findings --detector-id "$DETECTOR_ID" --finding-ids "$FINDING_ID" --query 'Findings[0].Service.Action.AwsApiCallAction.RemoteIpDetails.IpAddressV4' --output text)
aws guardduty create-filter \
--detector-id "$DETECTOR_ID" \
--name "SuppressInstanceCredentialExfiltrationOutsideAWS" \
--description "Suppress InstanceCredentialExfiltration OutsideAWS" \
--finding-criteria "{\"Criterion\": {\"type\": {\"Eq\": [\"UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS\"]}, \"service.action.awsApiCallAction.remoteIpDetails.ipAddressV4\": {\"Eq\": [\"$IP_ADDRESS\"]}}}"
UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.InsideAWS
複数アカウントのネットワークの集約などを行っている場合に検知されることがあります。
FINDING_ID={検知された検出結果ID}
DETECTOR_ID=$(aws guardduty list-detectors --query 'DetectorIds[0]' --output text)
ACCOUNT_ID=$(aws guardduty get-findings --detector-id "$DETECTOR_ID" --finding-ids "$FINDING_ID" --query 'Findings[0].Service.Action.AwsApiCallAction.RemoteAccountDetails.AccountId' --output text)
aws guardduty create-filter \
--detector-id "$DETECTOR_ID" \
--name "SuppressInstanceCredentialExfiltrationInsideAWS" \
--description "Suppress InstanceCredentialExfiltration InsideAWS for aggregated accounts" \
--finding-criteria "{\"Criterion\": {\"type\": {\"Eq\": [\"UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.InsideAWS\"]}, \"service.action.awsApiCallAction.remoteAccountDetails.accountId\": {\"Eq\": [\"$ACCOUNT_ID\"]}}}"
Discovery:IAMUser/AnomalousBehavior
出張先などいつもと違う場所から AWS へアクセスした際に検知されることがあります。以下の条件のフィルターを作成しています。
- Severity: 低(Low)
- API caller country: API 発信国
- API caller IPv4 address: API 発信者の IPv4 アドレス
FINDING_ID={検知された検出結果ID}
DETECTOR_ID=$(aws guardduty list-detectors --query 'DetectorIds[0]' --output text)
COUNTRY=$(aws guardduty get-findings --detector-id "$DETECTOR_ID" --finding-ids "$FINDING_ID" --query 'Findings[0].Service.Action.AwsApiCallAction.RemoteIpDetails.Country.CountryName' --output text)
IP_ADDRESS=$(aws guardduty get-findings --detector-id "$DETECTOR_ID" --finding-ids "$FINDING_ID" --query 'Findings[0].Service.Action.AwsApiCallAction.RemoteIpDetails.IpAddressV4' --output text)
aws guardduty create-filter \
--detector-id "$DETECTOR_ID" \
--name "SuppressAnomalousBehaviorLowSeverity" \
--description "Suppress AnomalousBehavior with low severity for known locations" \
--finding-criteria "{\"Criterion\": {\"type\": {\"Eq\": [\"Discovery:IAMUser/AnomalousBehavior\"]}, \"severity\": {\"Eq\": [\"1\",\"2\",\"3\"]}, \"service.action.awsApiCallAction.remoteIpDetails.country.countryName\": {\"Eq\": [\"$COUNTRY\"]}, \"service.action.awsApiCallAction.remoteIpDetails.ipAddressV4\": {\"Eq\": [\"$IP_ADDRESS\"]}}}"
DefenseEvasion:EC2/UnusualDNSResolver
8.8.8.8 のようなパブリックな DNS サーバーを利用した場合に検知されることがあります。IP アドレスは検知内容に合わせて変更してください。
FINDING_ID={検知された検出結果ID}
DETECTOR_ID=$(aws guardduty list-detectors --query 'DetectorIds[0]' --output text)
IP_ADDRESS=$(aws guardduty get-findings --detector-id "$DETECTOR_ID" --finding-ids "$FINDING_ID" --query 'Findings[0].Service.Action.NetworkConnectionAction.RemoteIpDetails.IpAddressV4' --output text)
aws guardduty create-filter \
--detector-id "$DETECTOR_ID" \
--name "SuppressUnusualDNSResolver" \
--description "Suppress UnusualDNSResolver for known public DNS resolvers" \
--finding-criteria "{\"Criterion\": {\"type\": {\"Eq\": [\"DefenseEvasion:EC2/UnusualDNSResolver\"]}, \"service.action.networkConnectionAction.remoteIpDetails.ipAddressV4\": {\"Eq\": [\"$IP_ADDRESS\"]}}}"
抑制ルールを削除
以下のコマンドで削除できます。${filter-name}
の値は設定したフィルター名に置き換えてください。
aws guardduty delete-filter \
--detector-id "$DETECTOR_ID" \
--filter-name "${filter-name}"
まとめ
GuardDuty の抑制ルールを CLI で作成してみました。意外と CLI から設定している例が少なかったので、参考になれば幸いです。